package com.wealth.wechat.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wealth.order.entity.OrderPlat;
import com.wealth.payment.entity.PaymentAccount;
import com.wealth.platform.entity.SldConfig;
import com.wealth.wechat.entity.WechatConfig;
import com.wealth.wechat.util.MD5Util;
import com.wealth.wechat.util.TrustSSL;
import com.wealth.wechat.util.XmlParser;

/**
 * 微信统一下单API
 * @author chan
 * 
 * 参考
 * --------------------------------
 * https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1
 */
@Service
public class WechatPayApi{
	
	Logger logger = Logger.getLogger(WechatPayApi.class);
	
	public static final String WXPAY_UNIFIEDORDER= "https://api.mch.weixin.qq.com/pay/unifiedorder";
	
	/**
	 * tradeType: 交易类型: JSAPI公众号支付,NATIVE--原生扫码支付
	 */
	public JSONObject getPayParam(WechatConfig config,SldConfig sldConfig,PaymentAccount payaccount,String tradeType,
			OrderPlat orderPlat,String openid,HttpServletRequest request) throws Exception{
		
		/* -------- 请求参数 -------- */
		String appid = config.getWxappid();																//应用ID
		String mch_id = payaccount.getPartnerid();													//商户号
		String nonce_str= RandomStringUtils.randomAlphanumeric(12);					//随机字符串
		String body = "订单编号:"+orderPlat.getOrderno();										//订单描述，商品或支付单简要描述
		String out_trade_no=orderPlat.getOrderno();													//商户订单号
		Double d = orderPlat.getTotal()*100;							
		String total_fee =String.valueOf(d.intValue()); 												//订单总金额,以一分钱为单位，只能为整数
		String spbill_create_ip= request.getRemoteAddr();											//终端IP
		String notify_url=sldConfig.getDomain()+"/pay/notify_url/"+orderPlat.getId();		//通知地址
		String trade_type = tradeType;									//交易类型
		
		SortedMap<String, String> packageParams = new TreeMap<String, String>();
		packageParams.put("appid", appid); 
		packageParams.put("mch_id",mch_id); 	  
		packageParams.put("nonce_str", nonce_str);  
		packageParams.put("body", body); 
		packageParams.put("out_trade_no", out_trade_no);
		packageParams.put("total_fee", total_fee);
		packageParams.put("spbill_create_ip", spbill_create_ip);
		packageParams.put("notify_url", notify_url);
		packageParams.put("trade_type", trade_type);
		//packageParams.put("openid", openid);
		//统一支付接口签名
		String packageValue = MD5Util.createSignAddKey(packageParams,payaccount.getPayservice());
		packageParams.put("sign", packageValue);
		//转换XML
		Map<String, Object> map_result = new HashMap<String, Object>();
		map_result.putAll(packageParams);
		String xmlSting =XmlParser.map2XmlStr(map_result,"XML");
		
		/* --------  请求接口，返回 -------- */
		String jsonStr = TrustSSL.sendNewRequest(WXPAY_UNIFIEDORDER, xmlSting);
		map_result=XmlParser.xmlStr2Map(jsonStr);
		//错误code
		map_result.put("errcode","00");
		//统一支付接口调用成功
		if(map_result!=null && map_result.get("return_code").equals("SUCCESS")){
			
			//微信生成的预支付成功
			if(map_result.get("result_code").equals("SUCCESS")){
				
				map_result.put("errcode","01");
				
				if(tradeType.equals("JSAPI")){
					//生成JSAPI 参数返回给H5端
					SortedMap<String, String> map_JSAPI = new TreeMap<String, String>();
					map_JSAPI.put("appId",appid);
					map_JSAPI.put("timeStamp",create_timestamp());
					map_JSAPI.put("nonceStr",nonce_str);
					map_JSAPI.put("package","prepay_id="+map_result.get("prepay_id"));
					map_JSAPI.put("signType","MD5");
					String paySign = MD5Util.createSignAddKey(map_JSAPI,payaccount.getPayservice());			//JSAPI签名
					map_JSAPI.put("paySign",paySign);
					map_result.putAll(map_JSAPI);
				}else if(tradeType.equals("NATIVE")){
					//生成NATIVE 参数返回
					SortedMap<String, String> map_native = new TreeMap<String, String>();
					map_native.put("code_url",map_result.get("code_url").toString());
					map_result.putAll(map_native);
				}
			}
			//微信生成的预支付失败
			else{
				//返回错误描述
				map_result.put("return_msg",map_result.get("err_code_des"));
			}
		}
		
		//处理返回  JSAPI 参数
		JSONObject result =JSONObject.parseObject(JSON.toJSONString(map_result));
		logger.info("统一支付接口jsonStr="+result);

		return result;
	}
	
	/**
	 * 当前的时间
	 * */
    private String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
	
	/**
	 * 从输入流读取post参数
	 * @param in
	 * @return
	 */
	public String readStreamParameter(ServletInputStream in){
		StringBuilder buffer = new StringBuilder();
		BufferedReader reader=null;
		try{
			reader = new BufferedReader(new InputStreamReader(in));
			String line=null;
			while((line = reader.readLine())!=null){
				buffer.append(line);
	        }
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if(null!=reader){
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return buffer.toString();
	}
    
	/**
	 * 发送流
	 * @param response
	 * @param sendstr
	 */
	public void sendStream(HttpServletResponse response, String sendstr){
		try{
			OutputStream os = response.getOutputStream();
			os.write(sendstr.getBytes());
			os.flush();
			os.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}
